package com.lisen.hsql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hsqldb.Server;

public class HsqlListener implements ServletContextListener {

	private String HSQL_DBPATH = "hsql.dbPath";
	private String HSQL_DBNAME = "hsql.dbName";
	private String HSQL_PORT = "hsql.port";
	protected Logger log = Logger.getLogger(getClass());

	protected Server server;

	@Override
	public void contextDestroyed(ServletContextEvent sce) {

		log.info("========  HsqlListener destroyed...");
		try {
			shutdownServer();
			log.info("======== hsqldb shutdown...");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void contextInitialized(ServletContextEvent sce) {

		String path = getDbPath(sce);
		if (!path.endsWith("/")) {
			path = path + "/";
		}
		if (StringUtils.isEmpty(path)) {
			log.info("======== Can't get " + HSQL_DBPATH
					+ " from web.xml Context Param");
			return;
		}
		log.debug("hsqldb_path:" + path);
		String dbName = sce.getServletContext().getInitParameter(HSQL_DBNAME);
		if (StringUtils.isEmpty(dbName)) {
			log.info("======= Can't get " + HSQL_DBNAME
					+ " from web.xml Context param");
			return;
		}
		int port = -1;
		try {
			port = Integer.parseInt(sce.getServletContext().getInitParameter(
					HSQL_PORT));
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}

		startServer(path, dbName, port);
	}

	private String getDbPath(ServletContextEvent sce) {
		String path = sce.getServletContext().getInitParameter(HSQL_DBPATH);
		if (path.startsWith("{user.home}")) {
			path = path.replaceFirst("\\{user.home\\}", System.getProperty(
					"user.home").replace('\\', '/'));
		}
		if (path.startsWith("{webapp.root}")) {
			path = path.replaceFirst("\\{webapp.root\\}", sce
					.getServletContext().getRealPath("/").replace('\\', '/'));
		}
		return path;
	}

	private void shutdownServer() {
		if (server == null) {
			throw new RuntimeException(" hsql has not startup...");
		} else {
			server.shutdown();
		}
	}

	private void startServer(String dbPath, String dbName, int port) {
		if(server==null){
			server = new Server();
		}else{
			shutdownServer();
		}
		server.setDatabaseName(0, dbName);
		server.setDatabasePath(0, dbPath + dbName);
		if (port != -1) {
			server.setPort(port);
		}
		server.setSilent(true);
		server.setTrace(true);

		server.start();
		log.info("======== hsqldb started...");
		try {
			Thread.sleep(800);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
